{
 "cells": [
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "8e46305e",
   "metadata": {},
   "source": [
    "## Looping\n",
    "\n",
    "The design pattern shown below is encouraged (when possible) for deploying multiple experiments using the `for` loop. This enables the independent experiments to be performed in parallel rather than sequentially.\n",
    "\n",
    "### Prerequisites\n",
    "\n",
    "Define an experiment in an electron or [sublattice](../execution/execute_sublattice.ipynb). "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "858e0d2d",
   "metadata": {},
   "outputs": [],
   "source": [
    "import covalent as ct\n",
    "import random\n",
    "\n",
    "@ct.electron\n",
    "def experiment(min_max=[0, 99]):          # A simple experiment in an electron (with default parameter set)\n",
    "    min, max = min_max[0], min_max[1]\n",
    "    return random.randint(min, max)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bec77f29",
   "metadata": {},
   "source": [
    "### Procedure\n",
    "\n",
    "1. Create a lattice from which to deploy multiple runs of your experiment.\n",
    "2. In the lattice, loop through an iterable containing a complete set of experimental parameters for each run of the experiment.\n",
    "3. Append the results of each run to a list of results. Since no single run of the experiment depends on the output of another run, Covalent parallelizes the loop and runs each experiment concurrently in its own executor (subject to limits imposed by the chosen executor pool).\n",
    "4. Return the list of results. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "b690e76a",
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "@ct.lattice\n",
    "def run_experiment(experiment_params=[[0,99]]):  # 1. A lattice for the experiment\n",
    "    res = []\n",
    "    for params in experiment_params:             # 2. Loop through the experimental parameters\n",
    "        res.append(experiment(params))           # 3. Append each result to a list\n",
    "    return res                                   # 4. Return the results"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b143cf0d",
   "metadata": {},
   "source": [
    "Dispatch the lattice, supplying an iterable with the experimental parameters."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "8b6ff2a5",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Lattice Result\n",
      "==============\n",
      "status: COMPLETED\n",
      "result: [1, 15, 27, 31, 43]\n",
      "input args: ['[[0, 9], [10, 19], [20, 29], [30, 39], [40, 49]]']\n",
      "input kwargs: {}\n",
      "error: None\n",
      "\n",
      "start_time: 2023-01-29 21:24:39.654830\n",
      "end_time: 2023-01-29 21:24:40.186362\n",
      "\n",
      "results_dir: /Users/mini-me/agnostiq/covalent/doc/source/how_to/coding/results\n",
      "dispatch_id: 9efced5d-5124-4fcc-aacb-5f544bdaf05b\n",
      "\n",
      "Node Outputs\n",
      "------------\n",
      "experiment(0): 1\n",
      ":electron_list:(1): [0, 9]\n",
      ":parameter:0(2): 0\n",
      ":parameter:9(3): 9\n",
      "experiment(4): 15\n",
      ":electron_list:(5): [10, 19]\n",
      ":parameter:10(6): 10\n",
      ":parameter:19(7): 19\n",
      "experiment(8): 27\n",
      ":electron_list:(9): [20, 29]\n",
      ":parameter:20(10): 20\n",
      ":parameter:29(11): 29\n",
      "experiment(12): 31\n",
      ":electron_list:(13): [30, 39]\n",
      ":parameter:30(14): 30\n",
      ":parameter:39(15): 39\n",
      "experiment(16): 43\n",
      ":electron_list:(17): [40, 49]\n",
      ":parameter:40(18): 40\n",
      ":parameter:49(19): 49\n",
      "\n"
     ]
    }
   ],
   "source": [
    "dispatch_id = ct.dispatch(run_experiment)([[0,9],[10,19],[20,29],[30,39],[40,49]])\n",
    "result = ct.get_result(dispatch_id, wait=True)\n",
    "print(result)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "5891b0a6",
   "metadata": {},
   "source": [
    "### See Also\n",
    "\n",
    "[Adding an Electron to a Lattice](./add_electron_to_lattice.ipynb)\n",
    "\n",
    "[Constructing a Sublattice](../execution/execute_sublattice.ipynb)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f7388494",
   "metadata": {},
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
